#include "visit.h"

void visit_varDecl(ASTNode *ctx, SymbolTable *s, Module *m, BasicBlock* bb) {
    string type = "int";
    
    type = visit_bType(ctx->children[0], s, bb);
    auto [var_name, data] = visit_varDef(ctx->children[1], s, m, bb);

    visit_argVarDecl(ctx->children[2], s, bb);

    if (s->lookup(var_name) != nullptr) {
        cout << "变量名" << var_name << "重复命名" << endl;
        throw std::invalid_argument("变量名重复命名");
    }
    

    if (auto* p = std::get_if<int>(&data)) {
        
        Type* i32_Type = m->get_int32_type();
        // 为局部变量分配内存
        AllocaInst* alloca = AllocaInst::create_alloca(i32_Type, bb);
        Value* initial_value = nullptr;
        

        // data 是 int 类型，直接创建常量
        int value;
        initial_value = ConstantInt::get(*p, m);
        value = *p;

        // 将初始值存储到 alloca 分配的内存中
        StoreInst::create_store(initial_value, alloca, bb);
        s->addSymbol(var_name, VAR, type, value, alloca, nullptr, nullptr, bb);
        
    } else if (auto* p = std::get_if<float>(&data)) {
        Type* float_type = m->get_float_type();
        // 为局部变量分配内存
        AllocaInst* alloca = AllocaInst::create_alloca(float_type, bb);
        Value* initial_value = nullptr;

        // data 是 float 类型
        float value;
        initial_value = ConstantFP::get(*p, m);
        value = *p;
        
        // 将初始值存储到 alloca 分配的内存中
        StoreInst::create_store(initial_value, alloca, bb);
        s->addSymbol(var_name, VAR, type, value, alloca, nullptr, nullptr, bb);
    } else if(auto* p = std::get_if<string>(&data)){
        
        Symbol* symbol_ident = s -> lookup(*p);

        variant<int, float> init_data;

        if(symbol_ident -> kind == VAR || symbol_ident -> kind == CONST){
            if(symbol_ident -> type == "int"){
                // LoadInst::create_load(m->get_int32_type(), symbol_ident->alloc, bb);
                init_data = int(symbol_ident -> value);
                
            }
            else if(symbol_ident -> type == "float"){
                // LoadInst::create_load(m->get_float_ptr_type(), symbol_ident->alloc, bb);
                init_data = float(symbol_ident -> value);
                
            }
            else {
                std::cerr << "visit_initVal :" << "不支持的类型: " << symbol_ident -> type << std::endl;
                throw std::invalid_argument(string("visit_initVal :") + "不支持的类型: " + symbol_ident -> type);
            }
        }
        else{
            std::cerr << "visit_initVal :" << "不支持的类型: " << symbol_ident -> kind << std::endl;
            throw std::invalid_argument(string("visit_initVal :") + "不支持的类型: " + to_string(symbol_ident -> kind));
        }

        if(auto* p = std::get_if<int>(&init_data)){
            Type* i32_Type = m->get_int32_type();
            // 为局部变量分配内存
            AllocaInst* alloca = AllocaInst::create_alloca(i32_Type, bb);
            

            // data 是 int 类型，直接创建常量
            int value;
            value = *p;

            // 将初始值存储到 alloca 分配的内存中
            StoreInst::create_store(symbol_ident->alloc, alloca, bb);
            s->addSymbol(var_name, VAR, type, value, alloca, nullptr, nullptr, bb);
            
        }        
        else if(auto* p = std::get_if<float>(&init_data)){
            Type* float_type = m->get_float_type();
            // 为局部变量分配内存
            AllocaInst* alloca = AllocaInst::create_alloca(float_type, bb);

            // data 是 float 类型
            float value;
            value = *p;
            
            // 将初始值存储到 alloca 分配的内存中
            StoreInst::create_store(symbol_ident->alloc, alloca, bb);
            s->addSymbol(var_name, VAR, type, value, alloca, nullptr, nullptr, bb);

        }

            
    }


    
    return;
}